package utils;

import java.util.HashMap;

import com.vaadin.navigator.Navigator;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;

import config.Parameters;

public class NavigatorUtils {

	/**
	 * Catalog to possible views for navigation
	 */

	public NavigatorUtils() {
	}

	/**
	 * NOT RCOMENDED TO USE IN DYNAMIC VIEWS as the view is created before the
	 * parameters are given Load all navigator possible views saved in
	 * Paramenters
	 * 
	 * @param navigator
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	// We can only load initially not dynamic view
	public static void loadViewCatalogToNavigator(Navigator navigator) throws Exception{

		HashMap<String, Boolean> loadedViews = new HashMap<String, Boolean>();

		// recorrem totes les View INI desde els parametres

		for (String[] view : Parameters.viewCatalog) {

			if (view[2].equalsIgnoreCase("INI")) {

				loadedViews.put(view[0], new Boolean(true));

				// anyadim al navigator
				try {
					navigator.addView(view[0], (Class<? extends View>) Class
							.forName(Parameters.VIEW_PACKAGE + view[1]));

				} catch (ClassNotFoundException e) {
					throw new Exception("NavigatorUtils.loadViewCatalogToNavigator");
				}
			}
		}

		// les marquem com a carregades

		SessionUtils.setSessionLoadedViews(loadedViews);

	}

	/**
	 * Before navigating to a view, this should have been created and added to
	 * the navigator
	 * 
	 * @param navigator
	 * @param viewName
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static void navigateTo(Navigator navigator, String viewName) throws Exception{

		// carguem les vistes inicialitzades

		HashMap<String, Boolean> loadedViews = SessionUtils
				.getSessionLoadedViews();
		Boolean isLoaded = loadedViews.get(viewName);

		// si la vista no esta cargada, la buscarem als parametres

		if (isLoaded == null) {

			for (String[] view : Parameters.viewCatalog) {

				if (view[0].equalsIgnoreCase(viewName)) {

					loadedViews.put(view[0], new Boolean(true));

					try {
						navigator.addView(view[0],
								(Class<? extends View>) Class
										.forName(Parameters.VIEW_PACKAGE
												+ view[1]));

					} catch (ClassNotFoundException e) {
						throw new Exception("NavigatorUtils.navigateTo");
					}

					// es suposa que nomes una coincidira
					break;
				}
			}
			// la marquem com a carregada
			SessionUtils.setSessionLoadedViews(loadedViews);
		}
		// Navigate to view
		navigator.navigateTo(viewName);
	}

	/**
	 * sets general view change listener
	 * 
	 * @param navigator
	 */
	@SuppressWarnings("serial")
	public static void navigatorAddViewChangeListener(final Navigator navigator) {

		navigator.addViewChangeListener(new ViewChangeListener() {

			@Override
			public boolean beforeViewChange(ViewChangeEvent event) {

				// Check if a user has logged in
				boolean isLoggedIn = SessionUtils.getSessionUser() != null;
				boolean isLoginView = event.getViewName().equals(
						Parameters.LOGIN_VIEW_NAME);
				boolean isLogOutView = event.getViewName().equals(
						Parameters.LOGOUT_VIEW_NAME);

				if (!isLoggedIn && !isLoginView && !isLogOutView) {
					// Redirect to login view always if a user has not yet
					// logged in
					navigator.navigateTo(Parameters.LOGIN_VIEW_NAME);
					return false;

				} else if (isLoggedIn && isLoginView) {
					// If someone tries to access to login view while logged in,
					// then cancel
					return false;
				}

				return true;
			}

			@Override
			public void afterViewChange(ViewChangeEvent event) {
			}
		});
	}
}
